package org.apache.lucene.index.tag;

import java.io.IOException;

import org.apache.lucene.index.TagBlockSkipListReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.index.TermDocs;
import org.apache.lucene.index.tag.TagIndex.TagTermInfo;
import org.apache.lucene.store.IndexInput;
import org.apache.lucene.util.BitVector;

public class TagSegmentTermDocs implements TermDocs {
  protected IndexInput input;
  protected int count;
  protected int df;
  protected BitVector deletedDocs;
  int doc = 0;
  int freq;

  private int skipInterval;
  private int maxSkipLevels;
  private TagBlockSkipListReader skipListReader;

  private long freqBasePointer;

  private long skipPointer;
  private boolean haveSkipped;
  
  public void seek(Term term) throws IOException {
    
  }
  
  void seek(TagTermInfo ti, Term term) throws IOException {
    count = 0;
    if (ti == null) {
      df = 0;
    } else {
      df = ti.docFreq;
      doc = 0;
      freqBasePointer = ti.postingsPointer;
      skipPointer = freqBasePointer + ti.skipOffset;
      input.seek(freqBasePointer);
      haveSkipped = false;
    }
  }
  
  public void close() throws IOException {
    input.close();
    if (skipListReader != null)
      skipListReader.close();
  }
  
  public int read(final int[] docs, final int[] freqs) throws IOException {
    final int length = docs.length;
    int i = 0;
    while (i < length && count < df) {
      final int docCode = input.readVInt();
      doc += docCode;
      count++;
      if (deletedDocs == null || !deletedDocs.get(doc)) {
        docs[i] = doc;
        ++i;
      }
    }
    return i;
  }

  public boolean next() throws IOException {
    while (true) {
      if (count == df)
        return false;

      int docCode = input.readVInt();
      doc += docCode;
      count++;
      if (deletedDocs == null || !deletedDocs.get(doc))
        break;
    }
    return true;
  }

  public boolean skipTo(int target) throws IOException {
    if (df >= skipInterval) { // optimized case
      if (skipListReader == null)
        skipListReader = new TagBlockSkipListReader((IndexInput) input.clone(), maxSkipLevels, skipInterval); // lazily
      // clone
      if (!haveSkipped) { // lazily initialize skip stream
        skipListReader.init(skipPointer, freqBasePointer, df);
        haveSkipped = true;
      }
      int newCount = skipListReader.skipTo(target);
      if (newCount > count) {
        input.seek(skipListReader.getPointer());
        doc = skipListReader.getDoc();
        count = newCount;
      }
    }
    do {
      if (!next())
        return false;
    } while (target > doc);
    return true;
  }
}
